<template>
  <el-dialog
      v-model="visible"
      :close-on-click-modal="false"
      :show-close="true"
      :title="props.title"
      :width="props.device === DeviceEnum.MOBILE ? '90%' : '70%'"
      class="tools-dialog"
      @close="props.closeDialog()"
  >
    <div class="dialog-content">
      <!-- 搜索区域 -->
      <div class="tool-search-container">
        <el-input
            v-model="toolPageQuery.name"
            placeholder="搜索工具名称"
            class="search-input"
            clearable
            @keyup.enter="handleSearch"
        >
          <template #prefix>
            <el-icon>
              <Search/>
            </el-icon>
          </template>
        </el-input>

        <el-select
            v-model="toolPageQuery.componentType"
            placeholder="工具类型"
            class="type-select"
            clearable
        >
          <el-option
              v-for="(label, key) in dictData['ai_tool_type']"
              :key="key"
              :label="label"
              :value="key"
          />
        </el-select>

        <el-button
            type="primary"
            class="search-btn"
            @click="handleSearch"
        >
          搜索
        </el-button>
      </div>

      <!-- Provider 横向滑动区域 -->
      <div v-if="toolsProviderList.length > 0" class="provider-scroll-bar">
        <div class="provider-list">
          <div
            v-for="provider in toolsProviderList"
            :key="provider.provider"
            :class="['provider-card', isProviderSelected(provider) ? 'selected' : '']"
            @click="toggleProviderSelection(provider)"
          >
            <div class="provider-icon">
              <svg-icon v-if="provider.providerIcon" :icon-class="provider.providerIcon" size="32px"/>
            </div>
            <div class="provider-info">
              <div class="provider-name">{{ provider.provider }}</div>
              <div class="provider-count">{{ provider.toolCount }} 个工具</div>
            </div>
          </div>
        </div>
      </div>

      <!-- 工具卡片区域 -->
      <div
          v-infinite-scroll="loadMore"
          :infinite-scroll-disabled="loading || noMoreData"
          infinite-scroll-distance="100"
          class="tools-container"
      >
        <div
            v-if="toolsList.length === 0 && !loading"
            class="empty-state"
        >
          <el-icon class="empty-icon">
            <Box/>
          </el-icon>
          <p>未找到相关工具</p>
        </div>

        <div class="tools-grid">
          <div
              v-for="tool in toolsList"
              :key="tool.id ?? -1"
              class="tool-card"
              :class="{ 'selected': selectedToolIds.includes(tool.id ?? -1) }"
              @click="toggleToolSelection(tool)"
          >
            <div class="card-header">
              <div class="tool-icon">
                <svg-icon v-if="tool.providerIcon" :icon-class="tool.providerIcon" size="25px"/>
              </div>
              <div class="tool-info">
                <h3 class="tool-name">{{ tool.name }}</h3>
                <div class="tool-provider">
                  <span>{{ tool.provider }}</span>
                </div>
              </div>
            </div>

            <div class="card-body">
              <p class="tool-description">{{ tool.description || '暂无描述信息' }}</p>
            </div>

            <div class="card-footer">
              <el-tag class="tool-type">
                {{ (dictData['ai_tool_type']?.[tool.componentType ?? ''] || tool.componentType || '未知类型') }}
              </el-tag>
            </div>

            <div class="selection-indicator">
              <el-icon v-if="selectedToolIds.includes(tool.id ?? -1)" class="selected-icon">
                <Select/>
              </el-icon>
            </div>
          </div>
        </div>

        <div v-if="loading" class="loading-state">
          <el-icon class="loading-icon">
            <Loading/>
          </el-icon>
          <span>加载中...</span>
        </div>

        <div v-if="noMoreData && toolsList.length > 0" class="no-more-data">
          没有更多数据了
        </div>
      </div>

      <!-- 底部操作按钮 -->
      <div class="dialog-footer">
        <div style="flex:1;display:flex;justify-content:flex-start;">
          <el-button @click="selectedToolIds = []">清除选择</el-button>
        </div>
        <div style="display:flex;gap:12px;">
          <el-button @click="props.closeDialog()">取消</el-button>
          <el-button type="primary" @click="handleConfirm">确认选择</el-button>
        </div>
      </div>
    </div>
  </el-dialog>
</template>

<script lang="ts" setup>
import {DeviceEnum} from "@/enums/DeviceEnum";
import {
  UserChatConversationDetailVO,
  UserChatToolPageQuery, UserChatToolProviderVO,
  UserChatToolVO
} from "@/api/ai/chat/user-chat/type";
import {UserChatAPI} from "@/api/ai/chat/user-chat";
import {useDictionary} from "@/hooks/userDict";

defineOptions({
  name: "ToolsInfoDialog",
  inheritAttrs: false,
});

const props = withDefaults(defineProps<{
  visible: boolean;
  title: string;
  device?: DeviceEnum;
  closeDialog: (callback?: () => void) => void;
  conversationId: string;
  currentConversationInfo?: UserChatConversationDetailVO
}>(), {
  currentConversationInfo: () => ({}) as UserChatConversationDetailVO,
  device: DeviceEnum.DESKTOP,
  dictData: () => ({})
});

const emits = defineEmits<{
  (event: "update:visible", visible: boolean): void
  (event: "update:currentConversationInfo", visible: boolean): void
}>()

// hooks
const visible = useVModel(props, 'visible', emits)
const currentConversationInfo = useVModel(props, 'currentConversationInfo', emits)
const dictData = await useDictionary(['ai_tool_type']); // 字典数据

// 数据
const toolPageQuery = ref<UserChatToolPageQuery>({
  componentType: undefined,   // 工具类型 : tool / mcp / agent ...
  name: undefined,            // 工具名称
  provider: undefined,        // 工具提供者
  pageNum: 1,
  pageSize: 30,
});

const toolsList = ref<UserChatToolVO[]>([]);  // 所有工具
const toolsProviderList = ref<UserChatToolProviderVO[]>([]); // 工具提供者列表
const loading = ref(false);                   // 加载状态
const total = ref(0);                         // 总数据量
const selectedToolIds = ref<number[]>([]);    // 选中的工具ID

// 计算属性：是否还有更多数据
const noMoreData = computed(() => {
  return toolsList.value.length >= total.value;
});

// 搜索工具
function handleSearch() {
  toolPageQuery.value.pageNum = 1;
  toolsList.value = [];
  loadTools();
}

// 加载工具数据
async function loadTools() {
  if (loading.value) return;

  try {
    loading.value = true;
    const {data} = await UserChatAPI.TOOL_PAGE.request(toolPageQuery.value);
    toolsList.value = [...toolsList.value, ...data.list];
    total.value = data.total;

    // 更新页码
    if (data.list.length > 0) {
      toolPageQuery.value.pageNum += 1;
    }
  } catch (error) {
    console.error('加载工具失败:', error);
    ElMessage.error('加载工具失败，请稍后重试');
  } finally {
    loading.value = false;
  }
}

async function loadToolProvider() {
  const {data} = await UserChatAPI.TOOL_PROVIDER_LIST.request();
  toolsProviderList.value = data.list ?? data;
}

// 滚动加载更多
function loadMore() {
  if (!loading.value && !noMoreData.value) {
    loadTools();
  }
}

// 切换工具选择状态
function toggleToolSelection(tool: UserChatToolVO) {
  const id = tool.id ?? -1;
  if (id === -1) return;

  const index = selectedToolIds.value.indexOf(id);
  if (index > -1) {
    selectedToolIds.value.splice(index, 1);
  } else {
    selectedToolIds.value.push(id);
  }
}

// 判断 provider 是否已全选
function isProviderSelected(provider: UserChatToolProviderVO) {
  if (!provider.toolIds || provider.toolIds.length === 0) return false;
  // provider 下所有工具都被选中才高亮
  return provider.toolIds.every(id => selectedToolIds.value.includes(id));
}

// 切换 provider 选择状态
function toggleProviderSelection(provider: UserChatToolProviderVO) {
  if (!provider.toolIds || provider.toolIds.length === 0) return;
  if (isProviderSelected(provider)) {
    // 只取消该 provider 下的工具，不影响其它 provider
    selectedToolIds.value = selectedToolIds.value.filter(id => !(provider.toolIds?.includes(id)));
  } else {
    // 合并选中该 provider 下所有工具
    const ids = new Set([...(selectedToolIds.value), ...provider.toolIds!]);
    selectedToolIds.value = Array.from(ids);
  }
}

// 确认选择
function handleConfirm() {
  // 工具ID数组对比（无序）
  const oldIds = (currentConversationInfo.value?.toolIds ?? []).slice().sort();
  const newIds = selectedToolIds.value.slice().sort();
  const isChanged = oldIds.length !== newIds.length || oldIds.some((id, idx) => id !== newIds[idx]);

  if (isChanged) {
    UserChatAPI.BIND_TOOLS.request({
      conversationId: props.conversationId,
      toolIds: selectedToolIds.value
    }).then(() => {
      // 同步更新当前会话的 toolIds
      if (currentConversationInfo.value) {
        currentConversationInfo.value.toolIds = selectedToolIds.value.slice();
      }
      ElMessage.success(`已绑定 ${selectedToolIds.value.length} 个工具`);
      props.closeDialog();
    }).catch(error => {
      props.closeDialog();
    });
  } else {
    ElMessage.success(`已绑定 ${selectedToolIds.value.length} 个工具`);
    props.closeDialog();
  }
}

// 初始化加载数据
onMounted(async () => {
  await loadTools();
  await loadToolProvider();
  selectedToolIds.value = (currentConversationInfo.value?.toolIds ?? []).slice();
});
</script>

<style lang="scss" scoped>
.tools-dialog {
  .dialog-content {
    display: flex;
    flex-direction: column;
    height: 70vh;

    .tool-search-container {
      display: flex;
      gap: 12px;
      margin-bottom: 20px;
      padding: 10px 10px;

      .search-input {
        flex: 1;
      }

      .type-select {
        width: 150px;
      }

      .search-btn {
        min-width: 80px;
      }

      @media (max-width: 768px) {
        flex-direction: column;

        .type-select, .search-btn {
          width: 100%;
        }
      }
    }

    .provider-scroll-bar {
      width: 100%;
      overflow-x: auto;
      margin-bottom: 18px;
      padding: 10px 10px;
      .provider-list {
        display: flex;
        flex-direction: row;
        gap: 16px;
        min-width: 100%;
      }
      .provider-card {
        min-width: 160px;
        max-width: 200px;
        border-radius: 10px;
        box-shadow: 0 2px 8px rgba(0,0,0,0.06);
        display: flex;
        align-items: center;
        padding: 10px 18px;
        cursor: pointer;
        transition: box-shadow 0.2s, transform 0.2s;
        border: 2px solid transparent;
        &:hover {
          box-shadow: 0 4px 16px rgba(64,158,255,0.12);
          border-color: var(--el-color-primary-light-5);
          transform: translateY(-2px) scale(1.03);
        }
        .provider-icon {
          margin-right: 12px;
          display: flex;
          align-items: center;
          justify-content: center;
          width: 40px;
          height: 40px;
          border-radius: 50%;
        }
        .provider-info {
          display: flex;
          flex-direction: column;
          .provider-name {
            font-size: 15px;
            font-weight: 600;
            color: var(--el-text-color-primary);
            margin-bottom: 2px;
          }
          .provider-count {
            font-size: 13px;
            color: var(--el-text-color-secondary);
          }
        }
        &.selected {
          border: 2.5px solid var(--el-color-primary) ;
          box-shadow: 0 6px 20px rgba(64,158,255,0.18);
        }
      }
    }
    @media (max-width: 768px) {
      .provider-scroll-bar {
        .provider-card {
          min-width: 120px;
          padding: 8px 10px;
          .provider-icon {
            width: 32px;
            height: 32px;
          }
          .provider-info {
            .provider-name {
              font-size: 13px;
            }
            .provider-count {
              font-size: 12px;
            }
          }
        }
      }
    }

    .tools-container {
      flex: 1;
      overflow-y: auto;
      padding: 10px 10px;

      .empty-state {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        height: 300px;
        color: var(--el-text-color-secondary);

        .empty-icon {
          font-size: 60px;
          margin-bottom: 20px;
          opacity: 0.5;
        }

        p {
          margin: 0;
          font-size: 16px;
        }
      }

      .tools-grid {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
        gap: 20px;

        @media (max-width: 768px) {
          grid-template-columns: 1fr;
        }
      }

      .tool-card {
        position: relative;
        border-radius: 12px;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
        padding: 20px;
        cursor: pointer;
        transition: all 0.3s ease;
        border: 2px solid transparent;
        overflow: hidden;

        &:hover {
          transform: translateY(-5px);
          box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1);
          border-color: var(--el-color-primary-light-5);
        }

        &.selected {
          border-color: var(--el-color-primary);
          background-color: rgba(64, 158, 255, 0.05);

          &::after {
            content: "";
            position: absolute;
            top: 0;
            right: 0;
            border-width: 0 40px 40px 0;
            border-style: solid;
            border-color: transparent var(--el-color-primary) transparent transparent;
          }
        }

        .card-header {
          display: flex;
          align-items: center;
          margin-bottom: 15px;

          .tool-icon {
            width: 50px;
            height: 50px;
            border-radius: 10px;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-right: 15px;
            overflow: hidden;
            flex-shrink: 0;

            img {
              width: 100%;
              height: 100%;
              object-fit: cover;
            }

            .default-icon {
              color: var(--el-color-primary);
              font-size: 24px;
            }
          }

          .tool-info {
            flex: 1;

            .tool-name {
              margin: 0;
              font-size: 16px;
              font-weight: 600;
              color: var(--el-text-color-primary);
              white-space: normal;
              word-break: break-all;
            }

            .tool-provider {
              font-size: 13px;
              color: var(--el-text-color-secondary);
              margin-top: 4px;
            }
          }
        }

        .card-body {
          .tool-description {
            margin: 0;
            font-size: 14px;
            color: var(--el-text-color-regular);
            line-height: 1.5;
            overflow: hidden;
            text-overflow: ellipsis;
            display: -webkit-box;
            -webkit-line-clamp: 3;
            -webkit-box-orient: vertical;
            min-height: 63px;
          }
        }

        .card-footer {
          margin-top: 15px;

          .tool-type {
            background: rgba(64, 158, 255, 0.1);
            color: var(--el-color-primary);
            border: none;
            font-weight: 500;
          }
        }

        .selection-indicator {
          position: absolute;
          top: 5px;
          right: 5px;

          .selected-icon {
            color: white;
            font-size: 14px;
            z-index: 1;
          }
        }
      }

      .loading-state {
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 20px;
        color: var(--el-text-color-secondary);

        .loading-icon {
          margin-right: 10px;
          animation: rotate 1.5s linear infinite;
        }
      }

      .no-more-data {
        text-align: center;
        padding: 20px;
        color: var(--el-text-color-secondary);
        font-size: 14px;
      }
    }

    .dialog-footer {
      display: flex;
      justify-content: flex-end;
      padding: 20px 10px 0;
      border-top: 1px solid var(--el-border-color-light);
      margin-top: 20px;

      .el-button {
        min-width: 100px;
        margin-left: 12px;
      }
    }
  }
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>